object implicitTest2 {
    trait Bifunctor[s <: Bifunctor[s]] requires s  {
      type a; type b
      def bimap[c, d](f :a=>c, g :b=>d) :s{type a=c; type b=d}
    }   
    
    // simulate equirecursive types
	implicit def unroll[s <: Bifunctor[s], ua](v :Fix[s,ua]) :s{type a=ua; type b=Fix[s,ua]} 
	               = v.out
	implicit def roll[s <: Bifunctor[s], ra](v :s{type a=ra; type b=Fix[s,ra]}) :Fix[s,ra] 
	               = Fix(v)
    
    case class Fix[s <: Bifunctor[s], fa](val out :s{type a=fa; type b=Fix[s,fa]}) { 
// without conversion: def map[mb](f :fa=>mb) :Fix[s,mb] = roll(unroll(this).bimap[mb,Fix[s,mb]](f, .map(f)))
// ideally: def map[mb](f :fa=>mb) :Fix[s,mb] = bimap(f, .map(f))
// should work according to spec (but may be considered as chaining):
//		def map[mb](f :fa=>mb) :Fix[s,mb] = this.bimap[mb,Fix[s,mb]](f, .map(f))
// should work according to spec:
		// def map[mb](f :fa=>mb) :Fix[s,mb] = roll(this.bimap[mb,Fix[s,mb]](f, .map(f)))

    }

   abstract class ListF extends Bifunctor[ListF]  
        case class NilF[la,lb] () extends ListF {
          type a=la; type b=lb       
          def bimap[c, d](f :a=>c, g :b=>d) :NilF[c,d] = NilF()
        }

        case class ConsF[la, lb] (x :la, y :lb) extends ListF {
          type a=la; type b=lb
          def bimap[c, d](f :a=>c, g :b=>d) :ConsF[c,d] = ConsF(f(x), g(y))
        }
    type List[a] = Fix[ListF, a]  

// ideally:	val list123 :List[Int] = ConsF(1, ConsF(2,  ConsF(3, NilF)))
	val n :Fix[ListF, Int] = NilF[Int,Fix[ListF,Int]]()
	def c (x :Int, t :Fix[ListF, Int]) :Fix[ListF, Int] = ConsF[Int,Fix[ListF,Int]](x, t) 
	val list123 :Fix[ListF, Int] = c(1, c(2,  c(3, n)))
}
